package net.sourceforge.gomoku

import reflect.BeanProperty
import collection.mutable.ListBuffer
import collection.mutable

/**
 * Created by IntelliJ IDEA.
 * User: denny
 * Date: Aug 19, 2010
 * Time: 1:48:18 PM
 * To change this template use File | Settings | File Templates.
 */

class Defensive(@BeanProperty val piece: Byte) extends Player{
  def pinside(board:Board, x:Int,y:Int)={
    x>=0 && y>=0 && x<board.getCols && y<board.getRows
  }

  case class Stick(x:Int,y:Int, dx:Int,dy:Int){
    def inside(board:Board)={
      (pinside(board, x,y)
        && pinside(board, x+dx*4,y+dy*4))
    }
    def cells={
      for( i <- 0 to 4 ) yield (x + dx*i, y + dy*i)
    }
    def opponentMarks(board:Board)={
      var m=0
      var dead=false
      for( i <- 0 to 4 ){
        val col = x + dx*i
        val row = y + dy*i
        val p = board.getPiece(row, col)
        if( p!=0 && p!=piece ){
          m += 1
        }
        if( p==piece ){
          dead=true // my mark is there, stick is never gonna win
        }
      }
      if( dead ) -1 else m
    }
    def firstEmptyCell(board:Board):Option[(Int,Int)]={
      var pos:Option[(Int,Int)] = None
      for( i <- 0 to 4 ){
        val col = x + dx*i
        val row = y + dy*i
        val p = board.getPiece(row, col)
        if( p==0 && pos.isEmpty ){
          pos = Some((col,row))
        }
      }
      pos
    }
  }

  def moveCalc(board:Board, maxFilled: Seq[Stick])={
    val counts = new mutable.HashMap[(Int,Int),Int]
    for( s <- maxFilled; c <- s.cells ){
      val (col,row) = c
      if( board.getPiece(row,col)==0 ){
        counts( (col,row) ) = counts.getOrElse( (col,row), 0 )+1
      }
    }

    val headCell = counts.toList.sortBy( -_._2 ).head
    printf("headCell %s %n", headCell)
    headCell._1
  }

  def makeMove(board: Board, opponentMove: Square):Square = {
    var m:Square=null

    val sticks = allSticks(board)
    val maxFilling = sticks.map( _.opponentMarks(board) ).max
    val maxFilled = sticks.filter( _.opponentMarks(board)==maxFilling )
//    val maxHead = maxFilled.head
//    printf("maxHead %s oppMarks=%d %n",maxHead, maxHead.opponentMarks(board))
//    val cell = maxHead.firstEmptyCell(board)
//    val (col,row) = cell.get

    val (col,row) = moveCalc(board, maxFilled)

    m = new NormalSquare(row, col);

//    for( row <- 0 until board.getRows; col <- 0 until board.getCols ){
//      if( m==null && board.getPiece(row, col)==0 ){
//        m = new NormalSquare(row, col);
//      }
//    }
    Thread.sleep(400)
    m
  }

  def allSticks(board: Board):Seq[Stick]={
    val all = new ListBuffer[Stick]
    for( row <- 0 until board.getRows; col <- 0 until board.getCols ){
      val dir = List(
        Stick(col,row, 1,0),
        Stick(col,row, 0,1),
        Stick(col,row, 1,1),
        Stick(col,row, -1,1))
      for( d <- dir; if d inside board){
        all += d
      }
    }
    all
  }

  def startNewGame = {}
}